home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug188 / hdrmsdos.c < prev    next >
Text File  |  1985-08-21  |  25KB  |  835 lines

  1. /* #include "bdscio.h"  */
  2.  
  3. /* in CI C86 need to compile this with the -u switch so that "char" is
  4.    treated as "unsigned char"
  5. */
  6.  
  7. #include "stdio.h"      /* CI C86 */
  8. #include "ctype.h"      /* CI C86 */
  9. #include "limits.h"     /* CI C86 */
  10. #include "setjmp.h"     /* CI C86 */
  11. #include "string.h"     /* CI C86 */
  12. #include "errno.h"      /* CI C86 */
  13. #include "stdlib.h"     /* CI C86 */
  14. #include "fileio2.h"    /* CI C86 */
  15. #undef  isspace         /* CI C86 */
  16. #define ERROR      0    /* CI C86 */
  17. #define OK        -1    /* CI C86 */
  18. #define FALSE      0    /* CI C86 */
  19. #define TRUE       1    /* CI C86 */
  20. char *ljust();          /* CI C86 */
  21. #define errmsg(num,str) printf("\n        Error %d: %s",(num),(str))/* CI C86 */
  22.  
  23.  
  24.  
  25. #define OPENCMNT   1
  26. #define HEADER     2
  27. #define ATTRIBUTE  3
  28. #define ENDCMNT    4
  29. #define TITLE      5
  30. #define VERSION    6
  31. #define DATE       7
  32. #define DESC       8
  33. #define KEYWD      9
  34. #define SYSTEM    10
  35. #define FNAME     11
  36. #define WARNING   12
  37. #define CRC       13
  38. #define ALSO      14
  39. #define AUTHOR    15
  40. #define COMP      16
  41. #define REF       17
  42. #define COMMA     18
  43. #define ENDREF    19
  44. #define REFAUTH   20
  45. #define REFTTL    21
  46. #define CITATION  22
  47. #define REFCIT    23
  48. #define COLON     24
  49. #define TOOLONG   25
  50. #define SEMI      26
  51. #define QUOTE     27
  52. #define FAULT     28
  53.  
  54. #define LEXSIZE 250
  55.  
  56. #define ON   1
  57. #define OFF  0
  58.  
  59. /* FILE source, list; */
  60. FILE *source, *list;     /* CI C86 */
  61.  
  62. /* char restart[6]; */
  63. jmp_buf *restart;        /* CI C86 */
  64. char catno[20];
  65. char lexval[LEXSIZE];
  66. int stoptoken;
  67. int debug, testonly;
  68. int parsing;
  69. int number;
  70.  
  71. main(argc,argv)
  72. int argc;
  73. char **argv;
  74.  
  75. {
  76. int fnumb, diskno;
  77. int i;
  78. char *lname;
  79. char *first;         /* CI C86 */
  80. char *next;          /* CI C86 */
  81. char filespec[255];  /* CI C86 */
  82. char *namestrt;      /* CI C86 */
  83. extern char *filedir(); /* CI C86 */
  84. extern char *upper();   /* CI C86 */
  85. extern unsigned char *strchr();  /* CI C86 */
  86. extern unsigned char *strrchr(); /* CI C86 */
  87.  
  88. /* if (wildexp(&argc,&argv) == ERROR)  / * CI C86 handles this differently * /
  89.    exit(puts("Wildexp Overflow\n"));    */
  90.  
  91. number = debug = testonly = OFF;
  92. fnumb = diskno = 0;
  93.  
  94. if (argc < 2) {
  95.     printf("USAGE:  header [-o<filespec>] [-t] [-d] [-nd] {<inpathspec>} \n\n"); /* CI C86 */
  96.     printf("   function:    Normally used to extract header information\n");
  97.     printf("                from the files in inpathspec, reformatting the\n");  /* CI C86 */
  98.     printf("                information in a fixed field format suitable\n");
  99.     printf("                for input to a relational database. The formatted\n");
  100.     printf("                output defaults to 'hdrout' on the current drive.\n\n");
  101.     printf("   options:     -o  use filespec for the list file name.\n");
  102.     printf("                -t  test only...checks syntax with no listing\n");
  103.     printf("                -n  number mode. Generates sequential file numbers\n");
  104.     printf("                    for all files on the disk. d is used as the\n");
  105.     printf("                    volume number. Headers consisting of only a \n");
  106.     printf("                    filename are generated for all files which don't\n");
  107.     printf("                    have a header. These are written to the list\n");
  108.     printf("                    file. Automatically sets -t, that is, since\n");
  109.     printf("                    the list file is being used to capture headers\n");
  110.     printf("                    no attempt is made to generate normal output.\n");
  111.     printf("                -d  debug...prints trace info to stdout.\n");
  112.     exit();
  113.     }
  114. lname="hdrout";
  115. for (i=1; i<argc; i++){
  116.    if (*argv[i] == '-'){
  117. /*    switch (*(argv[i]+1)){ */
  118.       switch (*upper(argv[i]+1)){                           /* CI C86 */
  119.          case 'D': debug = ON; break;
  120.          case 'T': testonly = ON; break;
  121.          case 'N': sscanf(argv[i]+2,"%d",&diskno);
  122.                    number = ON;
  123.                    testonly = ON;
  124.                    if (diskno < 100){
  125.                       printf("\nCUG numbers start at 100!\n");
  126.                       exit();
  127.                       }
  128.                    break;
  129.          case 'O': lname= argv[i]+2;
  130.                    break;
  131.          default:  printf("\nUnrecognized option %s",argv[i]);
  132.                    break;
  133.          }
  134.       }
  135.    if (debug) printf("\nargv[%d] = %s",i,argv[i]);   /* CI C86 */
  136.    }
  137.  
  138. if ((!testonly) || number) openlist(lname);
  139. if (debug) printf("\n open list passed");
  140.  
  141. for (i=1; i<argc; i++){
  142.    if (*argv[i] != '-'){
  143.  
  144.      strcpy(filespec,upper(argv[i]));                           /* CI C86 */
  145.      if (debug) printf("\nExpanding filespec %s",filespec);     /* CI C86 */
  146.      if ((namestrt = strrchr(filespec,'\\')) == NULL)           /* CI C86 */
  147.        if ((namestrt = strchr(filespec,':')) == NULL)           /* CI C86 */
  148.          namestrt = filespec - 1;                               /* CI C86 */
  149.      namestrt += 1;                                             /* CI C86 */
  150.      if ((first = filedir(filespec,0)) == NULL)                 /* CI C86 */
  151.        { printf("\nNo files match %s",filespec);                /* CI C86 */
  152.          continue; /* with next argv */                         /* CI C86 */
  153.        };                                                       /* CI C86 */
  154.      for (next = first; *next != NULL; next +=(strlen(next)+1)) /* CI C86 */
  155.       {                                                         /* CI C86 */
  156.        strcpy(namestrt,next); /* add name to drive:\path spec *//* CI C86 */
  157. /*     printf("\n%-15s",argv[i]);  */
  158.        printf("\n%s",filespec);                                 /* CI C86 */
  159. /*     if (fopen(argv[i],source) == ERROR) printf(" ...Can't open ");*/
  160.        if ((source=fopen(filespec,"r")) == NULL)                /* CI C86 */
  161.                                      printf(" ...Can't open "); /* CI C86 */
  162.  
  163.        else {
  164.           if (debug) {                                          /* CI C86 */
  165.              putchar('\n');                                     /* CI C86 */
  166.              for (debug=1;debug++ < 160;)                       /* CI C86 */
  167.                 printf("%c",getc(source));                      /* CI C86 */
  168.              rewind(source); debug=ON;                          /* CI C86 */
  169.              };                                                 /* CI C86 */
  170.           if (number) {
  171.              fnumb++;
  172. /*           if (dofile() == OK) numfile(argv[i], diskno, fnumb);*/
  173.              if (dofile() == OK) numfile(namestrt,diskno, \
  174.                                          fnumb,filespec);    /* CI C86 */
  175.              else {
  176.                 fclose(source);
  177.                 fprintf(list,"/* HEADER: CUG%03d.%02d; FILENAME: %s; */\n",
  178. /*                           diskno,fnumb,argv[i]); */
  179.                              diskno,fnumb,namestrt);         /* CI C86 */
  180.                 }
  181.              }
  182.           else {
  183.              dofile();
  184.              fclose(source);
  185.              }
  186.           }         /* of opening one source file */         /* CI C86 */
  187.        }            /* of expanding one filespec  */         /* CI C86 */
  188.        free(first);                                          /* CI C86 */
  189.      }              /* of *argv[i] != '-' */                 /* CI C86 */
  190.     }               /* of loop thru all argv[] values */     /* CI C86 */
  191.  
  192. if ((!testonly) || number){
  193.    fprintf(list,"%c",0x1a);
  194.    fflush(list);
  195.    fclose(list);
  196.    }
  197. }
  198.  
  199. /*
  200.    process a single file, adding results to output file
  201. */
  202. int dofile()
  203. {
  204. int att;
  205. int laterpass;
  206.  
  207. parsing = FAULT;
  208. laterpass = setjmp(restart);
  209. if (laterpass) return OK;
  210.  
  211. if (scantoken() != OPENCMNT) {
  212.    printf(" ...File doesn't begin with comment");
  213.    return !OK;
  214.    }
  215. if (scantoken() != HEADER) {
  216.    printf(" ...First comment isn't header ");
  217.    return !OK;
  218.    }
  219. printf(" ...Processing header");
  220. if (scantoken() != COLON) {
  221.    printf(" ...No colon after header keywork");
  222.    return !OK;
  223.    }
  224. scancatno(); /* sets catno as sideeffect */
  225. printf(" %9s",catno);                                          /* CI C86 */
  226. if (scantoken() != SEMI) faterr(4,"Expecting semi after cat. no.");
  227. while (tokentype(att=scantoken())==ATTRIBUTE) scanatt(att);
  228. if (stoptoken != ENDCMNT) faterr(5,"Header must end with comment delimiter");
  229. while(dohdr()==OK);  /*do following headers */
  230. return OK;
  231. }
  232.  
  233. int dohdr()
  234. {
  235. int att;
  236. int laterpass;
  237.  
  238. parsing = FAULT;
  239. laterpass = setjmp(restart);
  240. if (laterpass) return !OK;
  241.  
  242. if (scantoken() != OPENCMNT) {
  243.    return !OK;
  244.    }
  245. if (scantoken() != HEADER) {
  246.    return !OK;
  247.    }
  248. printf("\n                ...and another");
  249. if (scantoken() != COLON) {
  250.    printf(" ...No colon after header keywork");
  251.    return !OK;
  252.    }
  253. scancatno(); /* sets catno as sideeffect */
  254. printf(" %9s",catno);                                          /* CI C86 */
  255. if (scantoken() != SEMI) faterr(4,"Expecting semi after cat. no.");
  256. while (tokentype(att=scantoken())==ATTRIBUTE) scanatt(att);
  257. if (stoptoken != ENDCMNT) faterr(5,"Header must end with comment delimiter");
  258. /* always scans one token beyond end of attribute, leaves */
  259. return OK;
  260. }
  261.  
  262. int scanatt(att)
  263. int att;
  264.  
  265. {
  266. parsing = att;
  267. if (scantoken() != COLON)
  268.     faterr(10, "Attribute name must be followed by colon");
  269.  
  270. switch(att){
  271.    case TITLE:
  272.           if (scanitem() != OK) faterr(10,"ITEM must follow TITLE");
  273.           generate(catno,TITLE,lexval);
  274.           scantoken();
  275.                break;
  276.    case VERSION:
  277.           if (scannumber() != OK) faterr(11,"version number needed");
  278.           generate(catno,VERSION,lexval);
  279.           scantoken();
  280.           break;
  281.    case DATE:
  282.           if (scandate() != OK) faterr(12,"date needed");
  283.           generate(catno,DATE,lexval);
  284.           scantoken();
  285.           break;
  286.    case DESC:
  287.           if (scanstring(DESC)==TOOLONG)
  288.               faterr(13,"string too long in description");
  289.                /*scanstring breaks its output into lines and outputs it
  290.                  as a side effect. More than 30 lines is treated as an
  291.                  error (TOOLONG) */
  292.           scantoken();
  293.           break;
  294.    case KEYWD:
  295.           if (scanlist(KEYWD)!= OK) faterr(14,"Bad keyword list ");
  296.           break;
  297.    case SYSTEM:
  298.           if (scanlist(SYSTEM)!= OK) faterr(15,"Bad System list");
  299.           break;
  300.    case FNAME:
  301.           if (scanfname() != OK) faterr(16,"Poorly formed filename");
  302.           generate(catno,FNAME,lexval);
  303.           scantoken();
  304.           break;
  305.    case WARNING:
  306.           if (scanstring(WARNING)==TOOLONG)
  307.               faterr(17,"string too long in warning field");
  308.           scantoken();
  309.           break;
  310.    case CRC:
  311.           if (scanhex() != OK) faterr(18,"poorly formed CRC number");
  312.           generate(catno,CRC,lexval);
  313.           scantoken();
  314.           break;
  315.    case ALSO:
  316.           if (scanlist(ALSO)!= OK) faterr(19,"Bad See-Also list"); break;
  317.    case AUTHOR:
  318.           if (scanlist(AUTHOR)!= OK) faterr(20,"Bad Author list");
  319.           break;
  320.    case COMP:
  321.           if(scanlist(COMP)!=OK) faterr(21,"Bad Compiler List"); break;
  322.    case REF:
  323.           scanreflist(); /*generates output as side-effect*/
  324.           break;
  325.    default: faterr(22,"Unrecognized attribute");
  326.    }
  327. if (stoptoken != SEMI) faterr(23,"semi-colons must terminate attributes");
  328. }
  329.  
  330. int scanlist(type)
  331. int type;
  332.  
  333. {
  334. do {
  335.     if (scanitem()!= OK) {
  336.         errmsg(30,"Item poorly formed");
  337.         return(!OK);
  338.         }
  339.     generate(catno,type,lexval);
  340.     } while (scantoken()==COMMA);
  341. return(OK);
  342. }
  343.  
  344. scanreflist()
  345.  
  346. {
  347. do{
  348.    if (scanref() != OK)
  349.       faterr(40,"Reference poorly formed");
  350.    /* generates output as side effect */
  351.    } while (scantoken()== SEMI);
  352. if (stoptoken!=ENDREF)
  353.     faterr(41,"List of references must end with ENDREF keyword");
  354. scantoken(); /*to load semicolon into stoptoken */
  355. }
  356.  
  357. int scanref()
  358.  
  359. {
  360. int stoken;                                                    /* CI C86 */
  361. stoken = scantoken();                                          /* CI C86 */
  362. if (stoken==ENDREF) {                                          /* CI C86 */
  363.     errmsg(50,"ENDREF may not follow a : or ;");               /* CI C86 */
  364.     return !OK;                                                /* CI C86 */
  365.     }                                                          /* CI C86 */
  366. /* if (scantoken()!=AUTHOR) { */
  367. if (stoken!=AUTHOR) {                                          /* CI C86 */
  368.     errmsg(50,"reference must begin with AUTHORS:");
  369.     return !OK;
  370.     }
  371. if (scantoken()!=COLON) {
  372.     errmsg(54,"AUTHOR keyword must be followed by colon");
  373.     return !OK;
  374.     }
  375. if (scanlist(REFAUTH)!=OK) {
  376.     errmsg(51,"Bad reference list");
  377.     return !OK;
  378.     }
  379. if (stoptoken!= SEMI){
  380.     errmsg(52,"Authors in reference must end with semicolon");
  381.     return !OK;
  382.     }
  383. if (scantoken() != TITLE) {
  384.     errmsg(52,"Title must follow authors in reference");
  385.     return !OK;
  386.     }
  387. if (scantoken() != COLON) {
  388.     errmsg(53,"TITLE keyword must be followed by colon");
  389.     return !OK;
  390.     }
  391. if (scanstring(REFTTL)==TOOLONG){
  392.     errmsg(55,"title in reference too long--missing end quote?");
  393.     return !OK;
  394.     }
  395. if (scantoken()!= SEMI){
  396.     errmsg(56,"title must end with semicolon in reference");
  397.     return !OK;
  398.     }
  399. if (scantoken()!=CITATION){
  400.     errmsg(57,"CITATION must follow title in reference");
  401.     return !OK;
  402.     }
  403. if (scantoken() != COLON){
  404.     errmsg(58,"Colon must follow keyword CITATION in reference");
  405.     return !OK;
  406.     }
  407. if (scanstring(REFCIT)==TOOLONG){
  408.     errmsg(59,"Citation too long -- missing end quote?");
  409.     return !OK;
  410.     }
  411. return OK;
  412. }
  413.  
  414. generate(fileid,fldtype,str)
  415. char *fileid, *str;
  416. int fldtype;
  417.  
  418. {
  419. if (!testonly)
  420.    fprintf(list,"%3d %9s %s\n",fldtype,fileid,ljust(str));
  421. }
  422.  
  423. int scanstring(boss)
  424. int boss;
  425.  
  426. {
  427. int i, lines;
  428. int tmp;
  429. char buff[120];
  430. char *tbuf;
  431.  
  432. lines = 0;
  433. tmp = 0;
  434.  
  435. if (scantoken() != QUOTE) errmsg(51,"missing opening quote");
  436. do {
  437.    i = 0;
  438.    lines += 1;
  439.    tbuf=buff;
  440.    while ((i++ < 80) && ((tmp = getc(source))!=0x0a)
  441.          && (tmp != '"'))
  442.          if (tmp != 0x0d)  *tbuf++ = tmp;
  443.    *tbuf = 0;
  444.    if (i >= 80) {
  445.       errmsg(52,"string line over 80 chars -- missing end quote??");
  446.       }
  447.    generate(catno,boss,buff);
  448.    } while ((tmp != '"') && (lines < 15));
  449. return (lines > 15)? TOOLONG: OK;
  450. }
  451.  
  452. int scandate()
  453. {
  454. int i,n,mo,day,year;
  455. char buff[256];
  456. char *tbuf;
  457.  
  458. n=mo=day=year=i=0;
  459. tbuf=buff;
  460. while (((*tbuf++ = getc(source)) != ';') && (i++ < 250));
  461. if (i > 250) {
  462.    errmsg(55,"unable to find date terminator");
  463.    return !OK;
  464.    }
  465. ungetc(';',source);
  466. *tbuf = 0;
  467. if (debug) printf("scanning /%s/ in date\n",buff);
  468. /* if ((n=sscanf(buff,"%d/%d/%d",&mo,&day,&year))!=3){ */
  469. if ((n=sscanf(buff,"%d/%d/%d",&mo,&day,&year))!=5){         /* CI C86 */
  470.    if (debug) printf("fscanf returns %d with %d %d %d\n",n,mo,day,year);
  471.    return !OK;
  472.    }
  473. if (debug) printf("fscanf returns %d with %d %d %d\n",n,mo,day,year);
  474. if ((mo < 1) || (mo > 12) || (day < 1) || (day > 31)){
  475.    return !OK;
  476.    }
  477. if ((year < 100) && (year >50)) year = 1900 + year;
  478. sprintf(lexval,"%02d/%02d/%04d",mo,day,year);
  479. return OK;
  480. }
  481.  
  482. int scantoken()
  483.  
  484. {
  485. int rval;
  486.  
  487. fillex();
  488. /* if (debug) printf("at scantoken start, lexval=/%s/\n",lexval); */
  489. if (debug) printf("\nat scantoken start, lexval=/%s/",lexval);/* CI C86 */
  490. switch (*lexval){
  491.    case '/': if (getc(source) == '*') rval =  OPENCMNT;
  492.              else rval = FAULT;
  493.              break;
  494.    case '*': if (getc(source) == '/') rval =  ENDCMNT;
  495.              else rval = FAULT;
  496.              break;
  497.    case ',': rval =  COMMA; break;
  498.    case '"': rval =  QUOTE; break;
  499.    case ':': rval =  COLON; break;
  500.    case ';': rval =  SEMI; break;
  501.    default:
  502.       if (!strcmp(lexval,"HEADER")) rval =  HEADER;
  503.       else if (!strcmp(lexval,"TITLE")) rval =  TITLE;
  504.       else if (!strcmp(lexval,"VERSION")) rval =  VERSION;
  505.       else if (!strcmp(lexval,"DATE")) rval =  DATE;
  506.       else if (!strcmp(lexval,"DESCRIPTION")) rval =  DESC;
  507.       else if (!strcmp(lexval,"KEYWORDS")) rval =  KEYWD;
  508.       else if (!strcmp(lexval,"SYSTEM")) rval =  SYSTEM;
  509.       else if (!strcmp(lexval,"FILENAME")) rval =  FNAME;
  510.       else if (!strcmp(lexval,"WARNINGS")) rval =  WARNING;
  511.       else if (!strcmp(lexval,"CRC")) rval =  CRC;
  512.       else if (!strcmp(lexval,"SEE-ALSO")) rval =  ALSO;
  513.       else if (!strcmp(lexval,"AUTHORS")) rval =  AUTHOR;
  514.       else if (!strcmp(lexval,"COMPILERS")) rval =  COMP;
  515.       else if (!strcmp(lexval,"REFERENCES")) rval =  REF;
  516.       else if (!strcmp(lexval,"ENDREF")) rval =  ENDREF;
  517.       else if (!strcmp(lexval,"CITATION")) rval =  CITATION;
  518.       else rval =  ERROR;
  519.       }
  520. stoptoken = rval;
  521. if (debug) printf("\nscantoken returns %d /%s/",rval,lexval);
  522. return rval;
  523. }
  524.  
  525. scancatno()
  526.  
  527. {
  528. int n,volume,file;
  529. char *tmp;
  530. char locbuf[512];
  531. char waste[512];
  532. char dot;
  533.  
  534. tmp=locbuf;
  535. n=510;
  536. do {
  537.     *tmp=getc(source);
  538.     if (!n--) faterr(73,"no semicolon following cat no.");
  539.     }while ( *tmp++ != ';');
  540. ungetc(';',source);
  541. *(--tmp) = 0;
  542. /* if ((n=sscanf(locbuf,"%sCUG%d%c%d",waste,&volume,&dot,&file))!=4){ */
  543. if ((n=sscanf(locbuf,"CUG%d%c%d",&volume,&dot,&file))!=6){     /* CI C86 */
  544.     if (debug) printf("\nfscanf returns %d",n);
  545. /*  if (debug) printf("\nfscanf returns /%s/ %d %d %d",waste,volume,dot,file);*/
  546.     if (debug) printf("\nfscanf returns %d %d %d",volume,dot,file);/* CI C86 */
  547.     faterr(71,"Bad catalog number");
  548.     }
  549. if (volume < 100) errmsg(72,"CUG disks begin at 100!");
  550. if (file > 99) errmsg(74,"File number greater than 100.");
  551. if (dot != '.') errmsg(75,"Period separates disk and file no.");
  552. sprintf(catno,"CUG%03d.%02d",volume,file);
  553. }
  554.  
  555. int tokentype(tkn)
  556. int tkn;
  557.  
  558. {
  559. switch (tkn){
  560.    case TITLE:
  561.    case VERSION:
  562.    case DATE:
  563.    case DESC:
  564.    case KEYWD:
  565.    case SYSTEM:
  566.    case FNAME:
  567.    case WARNING:
  568.    case CRC:
  569.    case ALSO:
  570.    case AUTHOR:
  571.    case COMP:
  572.    case REF:
  573.         return ATTRIBUTE;
  574.    default:
  575.         return !ATTRIBUTE;
  576.    }
  577. }
  578.  
  579. int scanitem()
  580. {
  581. int tmp;
  582. char *tpt;
  583.  
  584. tpt=lexval;
  585. while (isspace(*tpt =     /* leading white space should */ /* CI C86 */
  586.           getc(source))); /* not be part of the item    */ /* CI C86 */
  587. ungetc(*tpt,source);                                       /* CI C86 */
  588. do {
  589.    stoptoken = *tpt++ = getc(source);
  590.    } while ((stoptoken != ',') && (stoptoken != ';'));
  591. *(--tpt) = 0;
  592. ungetc(stoptoken,source);
  593. tmp=strlen(lexval);
  594. if (debug) printf("\nscanitem /%s/ %d",lexval,tmp);        /* CI C86 */
  595. if ((tmp>40)||(tmp<1)) return !OK;
  596. return OK;
  597. }
  598.  
  599. fillex()
  600. {
  601. int i;
  602. char *pnt;
  603.  
  604. if (debug) printf("\nfillex entered");
  605. pnt=lexval;
  606. i=0;
  607. do{
  608.    *pnt=getc(source);
  609. /* if (debug) printf("\n  getc=%02.2x",*pnt); */
  610.    if (debug) printf("\n  getc=%02x",*pnt);              /* CI C86 */
  611.    } while (isspace(*pnt));
  612. if (debug) printf("\nwhitespace loop passed");
  613. stoptoken = *pnt;
  614. if (!isterm(*pnt)){
  615.     do{
  616.         *(++pnt) = getc(source);
  617.        }while (!isterm(*pnt) && (i++ < (LEXSIZE-3)));
  618.     stoptoken = *pnt--;
  619.     ungetc(stoptoken,source);
  620.     }
  621. *(++pnt)='\0';
  622. if (debug) printf("\nfillex exited lexval = /%s/",lexval);
  623. }
  624.  
  625. faterr(id,str)
  626. int id;
  627. char *str;
  628.  
  629. {
  630. char *parstask;
  631. switch (parsing){
  632.    case OPENCMNT:
  633.    case HEADER:
  634.    case ATTRIBUTE: parstask = "header beginning"; break;
  635.    case TITLE:     parstask = "title";break;
  636.    case VERSION:   parstask = "version"; break;
  637.    case DATE:      parstask = "date"; break;
  638.    case DESC:      parstask = "description"; break;
  639.    case KEYWD:     parstask = "keywords"; break;
  640.    case SYSTEM:    parstask = "operating systems"; break;
  641.    case FNAME:     parstask = "filename"; break;
  642.    case WARNING:   parstask = "warnings"; break;
  643.    case CRC:       parstask = "crck"; break;
  644.    case ALSO:      parstask = "see-also"; break;
  645.    case AUTHOR:    parstask = "authors"; break;
  646.    case COMP:      parstask = "compilers"; break;
  647.    case REF:       parstask = "references"; break;
  648.    default:        parstask = 0; break;
  649.    }
  650.  
  651. if (parstask) printf("\n               %3d: %s in %s field",id,str,parstask);
  652. else          printf("\n               %3d: %s",id,str);
  653. longjmp(restart,1);
  654. }
  655.  
  656. int readwd(pnt)
  657. char *pnt;
  658.  
  659. {
  660. int i;
  661.  
  662. i=0;
  663. while (isspace(*pnt = getc(source))) pnt++;
  664. while ((*pnt != '"') && (!isspace(*pnt))){
  665.     pnt++;i++;
  666.     *pnt = getc(source);
  667.     }
  668. ungetc(*pnt, source);
  669. *pnt ='\0';
  670. return i;
  671. }
  672.  
  673. int scanhex()
  674. {
  675. int val;
  676.  
  677. if (fscanf(source,"%x",&val)!= 1) return !OK;
  678. sprintf(lexval,"%04x",val);
  679. return OK;
  680. }
  681.  
  682. int scannumb()
  683.  
  684. {
  685. int fract;
  686.  
  687. fillex();
  688.  
  689. if (!isdigit(lexval[0])) {
  690.    errmsg(95,"version number must begin with digit");
  691.    return !OK;
  692.    }
  693. if (lexval[1] == '.'){
  694.    if (!isdigit(lexval[2])){
  695.       errmsg(90,"digit must follow '.' in version number");
  696.       return !OK;
  697.       }
  698.    if (isdigit(lexval[3]) && isdigit(lexval[4])){
  699.       errmsg(91,"only two digits may follow '.' in version number");
  700.       return !OK;
  701.       }
  702.    return OK;
  703.    }
  704. else if (lexval[2] == '.'){
  705.    if (!isdigit(lexval[3])){
  706.       errmsg(92,"digit must follow '.' in version number");
  707.       return !OK;
  708.       }
  709.    if (isdigit(lexval[4]) && isdigit(lexval[5])){
  710.       errmsg(93,"only two digits may follow '.' in version number");
  711.       return !OK;
  712.       }
  713.    return OK;
  714.    }
  715. else {
  716.    errmsg(94,"version number must contain period");
  717.    return !OK;
  718.    }
  719. }
  720.  
  721. int scanfname()
  722. {
  723. fillex();
  724. return OK;
  725. }
  726.  
  727. opensource(str)
  728. char *str;
  729.  
  730. {
  731. /* fopen(str,source);*/
  732. if ((source = fopen(str,"a")) == NULL)                /* CI C86 */
  733.    abort ("fopen of source file %s failed",str);      /* CI C86 */
  734. }
  735.  
  736. openlist(str)
  737. char *str;
  738. {
  739. /* fcreat(str,list);*/
  740. if ((list = fopen(str,"w")) == NULL)                 /* CI C86 */
  741.    abort ("fopen of list file %s failed",str);       /* CI C86 */
  742. }
  743.  
  744. int isspace(ch)
  745. char ch;
  746.  
  747. {
  748. return (ch <= ' ');
  749. }
  750.  
  751. int isterm(ch)
  752. char ch;
  753.  
  754. {
  755. switch (ch) {
  756.    case 0x0d:
  757.    case 0x0a:
  758.    case ' ':
  759.    case ':':
  760.    case ',':
  761.    case '"':
  762.    case ';':
  763.    case '*':
  764.    case '/':
  765.    case 0xff:                                           /* CI C86 */
  766.              return TRUE;
  767.              break;
  768.    default: return FALSE;
  769.    }
  770. }
  771.  
  772. char *ljust(str)
  773. char *str;
  774.  
  775. {
  776. while ((*str) && (isspace(*str))) str++;
  777. return str;
  778. }
  779.  
  780. /* numfile(name,disk,file) */
  781. numfile(name,disk,file,spec)                                  /* CI C86 */
  782. char *name;
  783. char *spec;                                                   /* CI C86 */
  784. int disk, file;
  785.  
  786. {
  787. char linebuf[512];
  788. /* FILE newfile; */
  789. FILE *newfile;                                                /* CI C86 */
  790. int ch,i;
  791. int st;
  792.  
  793. i=0;
  794. st=fclose(source);
  795. if (debug) printf("\nnum: close source returns %d",st);
  796. /* st=fopen(name,source);
  797.    if (debug) printf("\nnum: fopen source returns %d",st); */
  798. source = fopen(spec,"r");                                     /* CI C86 */
  799. if (source == NULL) abort("Could not open %s",spec);          /* CI C86 */
  800. if (debug) printf("\nnum: fopen source returns %d",source);   /* CI C86 */
  801. /* st=fcreat("HDR.$$$",newfile);
  802.    if (debug) printf("\nnum: fcreat newfile returns %d",st); */
  803. newfile = fopen("HDR.$$$","w");                               /* CI C86 */
  804. if (newfile == NULL) abort("Could not open HDR.$$$");         /* CI C86 */
  805. if (debug) printf("\nnum: fcreat newfile returns %d",newfile);/* CI C86 */
  806. while((ch = getc(source)) != ':') putc(ch,newfile);
  807. putc(ch,newfile);
  808. fprintf(newfile,"  CUG%03d.%02d;",disk,file);
  809. while ((getc(source) != ';') && (i++ < 200));
  810. if (i >= 200) {
  811.    printf(" ...volume number must end in semicolon");
  812.    st= fclose(newfile);
  813.    if(debug) printf("\nnum: fclose(newfile) returns %d",st);
  814.    st= unlink("HDR.$$$");
  815.    if (debug) printf("\nnum: unlink(temp) returns %d",st);
  816.    st=fclose(source);
  817.    if (debug) printf("\nnum: fclose source returns %d",st);
  818.    return;
  819.    }
  820. while(fgets(linebuf,source)) fputs(linebuf,newfile);
  821. fprintf(newfile,"\n%c",0x1a);
  822. st=fflush(newfile);
  823. if (debug) printf("\nnum: fflush newfile returns %d",st);
  824. st=fclose(newfile);
  825. if (debug) printf("\nnum: fclose newfile returns %d",st);
  826. st=fclose(source);
  827. if (debug) printf("\nnum: last fclose source returns %d",st);
  828. st=rename(name,"NUM.BAK");
  829. if (debug) printf("\nnum: rename source returns %d",st);
  830. st=rename("HDR.$$$",name);
  831. if (debug) printf("\nnum: rename temp returns %d",st);
  832. st=unlink("NUM.BAK");
  833. if (debug) printf("\nnum: unlink bak returns %d",st);
  834. }
  835.